//把毫秒 变成秒
// export const timestamp = (value) => {
//     return value / 1000;
//   };

import dayjs from "dayjs";
// import * as XLSX from "xlsx"; // Vue3 版本
import { ElMessage } from "element-plus";

import CryptoJS from "crypto-js";
let IV = null;
let KEY = null;

export const wrapperEnv = () => {
  //  console.log("NODE_ENV", process.env.NODE_ENV);

  const baseURL =
    process.env.NODE_ENV === "development"
      ? "https://test-api.payfaz.cc/"
      : "https://api.payfaz.cc/";

  return baseURL;
};

export const retainTwoDecimals = (num, type) => {
  if (type == "balance") {
    return Math.floor(num * 100) / 100;
  } else {
    return Math.floor(num * 100000000) / 100000000;
  }
};

export const truncateDecimals = (num, digits) => {
  var numStr = num.toString();
  // 如果没有小数点，则直接补足指定位数的小数并返回
  // if (numStr.indexOf(".") === -1) {
  //   return num.toFixed(digits);
  // }

  // 分割整数部分和小数部分
  var parts = numStr.split(".");
  var integerPart = parts[0];
  var decimalPart = parts[1];

  // 如果小数部分超过指定的位数，则截取前指定位数
  if (decimalPart && decimalPart.length > digits) {
    decimalPart = decimalPart.substring(0, digits);
  }

  // 补足不足指定位数的部分
  // decimalPart = decimalPart.padEnd(digits, "0");

  // 拼接整数部分和处理后的小数部分
  if (decimalPart) {
    return integerPart + "." + decimalPart;
  } else {
    return integerPart;
  }
};

/*
 * 权限判断，决定是否放行
 */
export const authorityJudgment = (callback) => {
  callback && callback();
};
export const formatDate = (v) => {
  if (v) {
    // 将Date()对象转成YYYY-MM-DD HH:MM:SS格式
    const year = v.getFullYear();
    const month = v.getMonth() + 1 < 10 ? `0${v.getMonth() + 1}` : v.getMonth();
    const day = v.getDate() + 1 < 10 ? `0${v.getDate() + 1}` : v.getDate();
    const hour = v.getHours() < 10 ? `0${v.getHours()}` : v.getHours();
    const minute = v.getMinutes() < 10 ? `0${v.getMinutes()}` : v.getMinutes();
    const second = v.getSeconds() < 10 ? `0${v.getSeconds()}` : v.getSeconds();
    return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
  }
  return "-";
};
// 将秒数转成YYYY-MM-DD HH:MM:SS格式
export const formatDates = (times, f) => {
  let fmt = "";
  if (f == "day") {
    fmt = "YYYY-MM-DD";
  } else if (f == "time") {
    fmt = "HH:mm:ss";
  } else {
    fmt = "YYYY-MM-DD HH:mm:ss";
  }
  return times > 0 ? dayjs.unix(times).format(fmt) : "-";
};

//格式化时间
export const formatterTime = (row, column, cellValue, f) => {
  //  const fmt = f == 'day' ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss"
  let fmt = "";
  if (f == "day") {
    fmt = "YYYY-MM-DD";
  } else if (f == "time") {
    fmt = "HH:mm:ss";
  } else {
    fmt = "YYYY-MM-DD HH:mm:ss";
  }
  return cellValue > 0 ? dayjs.unix(cellValue).format(fmt) : "-";
};
//格式化时间
export const formatterUtcTime = (row, column, cellValue, index) => {
  const tmp = new Date(cellValue);
  return formatDate(tmp);
  // return cellValue > 0 ? dayjs.unix(tmp).format("YYYY-MM-DD HH:mm:ss") : "-";
};
// 格式化转换 是、否
export const formatter = (row, column, cellValue, index) => {
  return cellValue ? "是" : "否";
};

//把毫秒 变成秒
export const timestamp = (value) => {
  return value / 1000;
};

//搜索框日期选择器默认时间
export const pickerDefaultTime = [
  new Date(0, 0, 0, 0, 0, 0),
  new Date(0, 0, 0, 23, 59, 59),
];

//处理数字千分位
export const numberToCurrencyNo = (value) => {
  if (!value) return 0;
  // 获取整数部分
  const intPart = Math.trunc(value);
  // 整数部分处理，增加,
  const intPartFormat = intPart
    .toString()
    .replace(/(\d)(?=(?:\d{3})+$)/g, "$1,");
  // 预定义小数部分
  let floatPart = "";
  // 将数值截取为小数部分和整数部分
  const valueArray = value.toString().split(".");
  if (valueArray.length === 2) {
    // 有小数部分
    floatPart = valueArray[1].toString(); // 取得小数部分
    return intPartFormat + "." + floatPart;
  }
  return intPartFormat + floatPart;
};

// 导出/下载Excel
export const exportExcel = (data, fileName) => {
  // data --数据流
  // fileName -- 文件名称
  const blob = new Blob([data], { type: "application/vnd.ms-excel" });
  const href = URL.createObjectURL(blob);
  const elink = document.createElement("a");
  elink.download = `${fileName}.xls`;
  elink.style.display = "none";
  elink.href = href;
  document.body.appendChild(elink);
  elink.click();
  document.body.removeChild(elink);
  URL.revokeObjectURL(href);
};

// 导出csv文件
export const exportCSV = (data, fileName) => {
  const blob = new Blob([data], { type: "text/csv;charset=utf-8;" });
  const href = URL.createObjectURL(blob);
  const elink = document.createElement("a");
  elink.href = href;
  elink.download = `${fileName}.csv`;
  elink.style.display = "none";
  document.body.appendChild(elink);
  elink.click();
  document.body.removeChild(elink);
  URL.revokeObjectURL(href);
};

// 银行卡号变星号
export const maskBankCardNumber = (cardNumber) => {
  if (!cardNumber || typeof cardNumber !== "string") {
    return cardNumber; // 如果输入无效，直接返回
  }

  const cardLength = cardNumber.length;
  if (cardLength === 0) {
    return ""; // 如果银行卡号为空，返回空字符串
  }

  // 创建一个由星号组成的字符串，长度与银行卡号相同
  const maskedNumber = cardLength > 0 ? "*".repeat(cardLength) : "";

  return maskedNumber;
};

export const generateMaskedString = () => {
  let maskedString = "";
  for (let i = 0; i < 12; i++) {
    maskedString += "*";
    if ((i + 1) % 4 === 0 && i < 11) {
      maskedString += " ";
    }
  }
  return maskedString;
};

// 清空对象值
export const resetForm = (source) => {
  Object.keys(source).forEach((key) => {
    if (source.hasOwnProperty(key)) {
      source[key] = "";
    }
  });
  return source;
};

// 生成16位随机字符串
export const generateRandomString = (length = 16) => {
  const characters =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let result = "";

  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * characters.length));
  }

  return result;
};

// base64
export const Base64 = {
  // private property
  _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

  encode: (input) => {
    let output = "";
    let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
    let i = 0;
    input = Base64._utf8_encode(input);
    while (i < input.length) {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);
      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;
      if (isNaN(chr2)) {
        enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
        enc4 = 64;
      }
      output =
        output +
        Base64._keyStr.charAt(enc1) +
        Base64._keyStr.charAt(enc2) +
        Base64._keyStr.charAt(enc3) +
        Base64._keyStr.charAt(enc4);
    }
    return output;
  },

  // public method for decoding
  decode: (input) => {
    let output = "";
    let chr1, chr2, chr3;
    let enc1, enc2, enc3, enc4;
    let i = 0;
    // todo []中括号里面使用转移符是多余的
    // input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '')
    input = input.replace(/[^A-Za-z0-9\u002b\u002f\u003d]/g, "");
    while (i < input.length) {
      enc1 = Base64._keyStr.indexOf(input.charAt(i++));
      enc2 = Base64._keyStr.indexOf(input.charAt(i++));
      enc3 = Base64._keyStr.indexOf(input.charAt(i++));
      enc4 = Base64._keyStr.indexOf(input.charAt(i++));
      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;
      output = output + String.fromCharCode(chr1);
      if (enc3 !== 64) {
        output = output + String.fromCharCode(chr2);
      }
      if (enc4 !== 64) {
        output = output + String.fromCharCode(chr3);
      }
    }
    output = Base64._utf8_decode(output);
    return output;
  },

  _utf8_encode: (string) => {
    string = string.replace(/\r\n/g, "\n");
    let utftext = "";
    for (let n = 0; n < string.length; n++) {
      let c = string.charCodeAt(n);
      if (c < 128) {
        utftext += String.fromCharCode(c);
      } else if (c > 127 && c < 2048) {
        utftext += String.fromCharCode((c >> 6) | 192);
        utftext += String.fromCharCode((c & 63) | 128);
      } else {
        utftext += String.fromCharCode((c >> 12) | 224);
        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
        utftext += String.fromCharCode((c & 63) | 128);
      }
    }
    return utftext;
  },

  _utf8_decode: (utftext) => {
    let string = "";
    let i = 0;
    let [c, c2, c3] = [0, 0, 0];
    while (i < utftext.length) {
      c = utftext.charCodeAt(i);
      if (c < 128) {
        string += String.fromCharCode(c);
        i++;
      } else if (c > 191 && c < 224) {
        c2 = utftext.charCodeAt(i + 1);
        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
        i += 2;
      } else {
        c2 = utftext.charCodeAt(i + 1);
        c3 = utftext.charCodeAt(i + 2);
        string += String.fromCharCode(
          ((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
        );
        i += 3;
      }
    }
    return string;
  },
};

// 加密
// 未登录：bs64(encrypt)
// 已登录：123+bs64(iv)+&+bs64(encrypt)
export const encrypt = (data, key, iv, prefix) => {
  let randomStr = "";
  if (iv) {
    randomStr = iv;
  } else {
    randomStr = generateRandomString();
  }
  IV = CryptoJS.enc.Utf8.parse(randomStr);
  // 如果有传递key的话使用传递的，否则使用默认的
  if (key) {
    KEY = CryptoJS.enc.Utf8.parse(key);
  } else {
    KEY = IV;
  }
  let srcs = CryptoJS.enc.Utf8.parse(data);
  let encrypted = CryptoJS.AES.encrypt(srcs, KEY, {
    iv: IV,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  // 判断如果未登录则不拼接，否则拼接
  let result = null;
  if (iv) {
    result =
      Base64.encode(iv) +
      "vXC8v" +
      CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
  } else {
    result =
      Base64.encode(prefix + randomStr) +
      "vXC8v" +
      CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
  }
  return result;
};

// 解密
export const decrypt = (word, key, iv) => {
  // 如果有传递key的话使用传递的，否则使用默认的
  if (key) {
    KEY = CryptoJS.enc.Utf8.parse(key);
  } else {
    KEY = IV;
  }
  let base64 = CryptoJS.enc.Base64.parse(word);
  let src = CryptoJS.enc.Base64.stringify(base64);
  var decrypt = CryptoJS.AES.decrypt(src, KEY, {
    iv: IV,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });

  var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return decryptedStr.toString();
};
